import { Writer } from "../thirdy/protobuf";

const { ccclass, property } = cc._decorator;

@ccclass
export default class Helloworld extends cc.Component {

    private serverURL: string = 'ws://localhost:8081';
    private socket: WebSocket = null;

    // 开始调用
    protected onLoad(): void {
        this.initWebSocketConnection();
    }

    start() {
        // 编码
        // const data = awesome.AwesomeMessage.encode(this.generateRandomMessage()).finish();

        /*
        let writer: Writer = awesome.AwesomeMessage.encode({ name: 'Jack', age: 12 });
        const data = writer.finish();

        console.log(`encode ${data}`);
        console.log(`serialize data ${this.serialize(10001, data)}`);

        // 解码
        const message = awesome.AwesomeMessage.decode(data);

        console.log(`decode ${JSON.stringify(message)}`);
        */
    }

    protected onDestroy(): void {
        this.closeWebSocketConnection();
    }

    // 初始化 WebSocket 连接
    initWebSocketConnection() {
        this.socket = new WebSocket(this.serverURL);
        this.socket.binaryType = "arraybuffer";

        this.socket.onopen = (event) => {
            console.log('WebSocket connected!');
            // 可以在此处发送初始数据到服务器
            // this.sendWebSocketData('hello-nb');

            // ⭐ 这里测试发送protobuf格式数据 ⭐
            let data = awesome.AwesomeMessage.encode({ name: 'Jack', age: 12 }).finish();
            this.sendWebSocketData(this.serialize(10001, data));
        };

        this.socket.onmessage = (event) => {
            let data1 = this.unSerialize(event.data);
        };

        this.socket.onerror = (error) => {
            console.error('WebSocket error: ', error);
        };

        this.socket.onclose = (event) => {
            console.log('WebSocket closed: ', event);
        };
    }

    // 发送数据到服务器
    sendWebSocketData(data) {
        if (this.socket && this.socket.readyState === WebSocket.OPEN) {
            // console.log(`send msg: ${data}`);
            // this.socket.send(data as string);
            this.socket.send(data);
        }
    }

    // 关闭 WebSocket 连接
    closeWebSocketConnection() {
        if (this.socket) {
            this.socket.close();
        }
    }

    // 序列化网络传输数据
    private serialize(msgId: number, bodyArray: Uint8Array): ArrayBuffer {
        let totalLen = 4;
        totalLen += (bodyArray.length * 1); // Uint8为一个字节

        // 写入消息编号
        let buf = new ArrayBuffer(totalLen);
        let dataView = new DataView(buf);
        dataView.setInt32(0, msgId);
        let offset = 4;
        // 写入消息体
        for (let i = 0; i < bodyArray.length; i++) {
            const element = bodyArray[i];
            dataView.setUint8(offset, element);
            offset += 1;
        }

        return dataView.buffer;
    }

    private unSerialize(arrayBuf: ArrayBuffer) {
        let dv = new DataView(arrayBuf);
        // 获取消息编号
        let msgId = dv.getInt32(0); // TODO: 大小端问题 dv.getInt32(0,true);
        // 获得消息体
        let body: Uint8Array = new Uint8Array(arrayBuf, 4);

        let data: any = awesome.AwesomeMessage.decode(body);
        console.log(`接收到的数据：msgId= ${msgId} ${JSON.stringify(data)}`);
    }
}
